﻿// -----------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Internal;

namespace System.ComponentModel.Composition
{
    public class CompositionBatch
    {
        private readonly ComposablePart[] _partsToAdd;
        private readonly ComposablePart[] _partsToRemove;
        public CompositionBatch()
        {
            this._partsToAdd = new ComposablePart[] { };
            this._partsToRemove = new ComposablePart[] { };
        }

        public CompositionBatch(IEnumerable<ComposablePart> partsToAdd, IEnumerable<ComposablePart> partsToRemove)
        {
            partsToAdd = partsToAdd ?? Enumerable.Empty<ComposablePart>();
            partsToRemove = partsToRemove ?? Enumerable.Empty<ComposablePart>();

            // If the same part is being added or removed in the same batch, they compensate each other
            this._partsToAdd = partsToAdd.ToArray();
            this._partsToRemove = partsToRemove.ToArray();
        }

        public IEnumerable<ComposablePart> PartsToAdd
        {
            get
            {
                return this._partsToAdd;
            }
        }

        public IEnumerable<ComposablePart> PartsToRemove
        {
            get
            {
                return this._partsToRemove;
            }
        }

        public CompositionBatch Add(ComposablePart part)
        {
            Requires.NotNull(part, "part");
            IEnumerable<ComposablePart> newPartsToAdd = this.PartsToAdd.Concat(new ComposablePart[] { part });
            return new CompositionBatch(newPartsToAdd, this.PartsToRemove);
        }

        public CompositionBatch Remove(ComposablePart part)
        {
            Requires.NotNull(part, "part");
            IEnumerable<ComposablePart> newPartsToRemove = this.PartsToRemove.Concat(new ComposablePart[] { part });
            return new CompositionBatch(this.PartsToAdd, newPartsToRemove);
        }

    }
}
